//
//  NSObject+runtime.m
//  OC运行时获取对象属性列表和方法列表
//
//  Created by Summer on 2017/11/20.
//  Copyright © 2017年 Summer. All rights reserved.
//

#import "NSObject+runtime.h"
#import <objc/runtime.h>

@implementation NSObject (runtime)

+ (NSArray *)getAllProperties
{
    u_int count;
    // 传递count的地址过去 &count
    objc_property_t *properties = class_copyPropertyList(self, &count);
    //arrayWithCapacity的效率稍微高那么一丢丢
    NSMutableArray *propertyArray = [NSMutableArray arrayWithCapacity:count];
    for (int i=0; i<count; i++) {
        // 此刻得到的propertyName为c语言的字符串
        const char* propertyName = property_getName(properties[i]);
        [propertyArray addObject:[NSString stringWithUTF8String:propertyName]];
    }
    
    //class_copyPropertyList底层为C语言，所以我们一定要记得释放properties
    // You must free the array with free().
    free(properties);
    return propertyArray;
}

+ (NSArray *)getAllMethods
{
    u_int count;
    Method *methodList = class_copyMethodList(self, &count);
    NSMutableArray *methodsArray = [NSMutableArray arrayWithCapacity:count];
    for (int i=0; i<count; i++) {
        Method temp = methodList[i];
        const char* name_s =sel_getName(method_getName(temp));
        [methodsArray addObject:[NSString stringWithUTF8String:name_s]];
    }
    free(methodList);
    return methodsArray;
}

+ (NSDictionary *)getAllPropertiesAndVaules:(NSObject *)obj
{
    NSMutableDictionary *propsDic = [NSMutableDictionary dictionary];
    unsigned int outCount;
    objc_property_t *properties =class_copyPropertyList([obj class], &outCount);
    for ( int i = 0; i<outCount; i++)
    {
        objc_property_t property = properties[i];
        const char* char_f =property_getName(property);
        NSString *propertyName = [NSString stringWithUTF8String:char_f];
        id propertyValue = [obj valueForKey:(NSString *)propertyName];
        if (propertyValue) {
            [propsDic setObject:propertyValue forKey:propertyName];
        }
    }
    free(properties);
    return propsDic;
}

@end
